home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 7 / rzsz0589.zip / ZMR.C < prev    next >
C/C++ Source or Header  |  1989-04-24  |  4KB  |  173 lines

  1. /*
  2.  * File: zmr.c 12-04-1988
  3.  * Copyright 1988 Omen Technology Inc All Rights Reserved
  4.  *
  5.  *
  6.  *    This code implements ZMODEM Run Length Encoding, not funded
  7.  *    by the original Telenet development contract.  This software,
  8.  *    including these features, may be freely used for non
  9.  *    commercial and educational purposes.  This software may also
  10.  *    be freely used to support file transfer operations to or from
  11.  *    licensed Omen Technology products.  Contact Omen Technology
  12.  *    for licensing for other uses.  Any programs which use part or
  13.  *    all of this software must be provided in source form with this
  14.  *    notice intact except by written permission from Omen
  15.  *    Technology Incorporated.
  16.  *
  17.  *        Omen Technology Inc        FAX: 503-621-3745
  18.  *        Post Office Box 4681
  19.  *        Portland OR 97208
  20.  *
  21.  *    This code is made available in the hope it will be useful,
  22.  *    BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
  23.  *    DAMAGES OF ANY KIND.
  24.  *    ZMODEM RLE compression and decompression functions
  25.  */
  26.  
  27. /* Send data subpacket RLE encoded with 32 bit FCS */
  28. zsdar32(buf, length, frameend)
  29. char *buf;
  30. {
  31.     register int c, l, n;
  32.     register UNSL long crc;
  33.  
  34.     crc = 0xFFFFFFFFL;  l = *buf++ & 0377;
  35.     if (length == 1) {
  36.         zsendline(l); crc = UPDC32(l, crc);
  37.         if (l == ZRESC) {
  38.             zsendline(1); crc = UPDC32(1, crc);
  39.         }
  40.     } else {
  41.         for (n = 0; --length >= 0; ++buf) {
  42.             if ((c = *buf & 0377) == l && n < 126 && length>0) {
  43.                 ++n;  continue;
  44.             }
  45.             switch (n) {
  46.             case 0:
  47.                 zsendline(l);
  48.                 crc = UPDC32(l, crc);
  49.                 if (l == ZRESC) {
  50.                     zsendline(0100); crc = UPDC32(0100, crc);
  51.                 }
  52.                 l = c; break;
  53.             case 1:
  54.                 if (l != ZRESC) {
  55.                     zsendline(l); zsendline(l);
  56.                     crc = UPDC32(l, crc);
  57.                     crc = UPDC32(l, crc);
  58.                     n = 0; l = c; break;
  59.                 }
  60.                 /* **** FALL THRU TO **** */
  61.             default:
  62.                 zsendline(ZRESC); crc = UPDC32(ZRESC, crc);
  63.                 if (l == 040 && n < 34) {
  64.                     n += 036;
  65.                     zsendline(n); crc = UPDC32(n, crc);
  66.                 }
  67.                 else {
  68.                     n += 0101;
  69.                     zsendline(n); crc = UPDC32(n, crc);
  70.                     zsendline(l); crc = UPDC32(l, crc);
  71.                 }
  72.                 n = 0; l = c; break;
  73.             }
  74.         }
  75.     }
  76.     xsendline(ZDLE); xsendline(frameend);
  77.     crc = UPDC32(frameend, crc);
  78.  
  79.     crc = ~crc;
  80.     for (length=4; --length >= 0;) {
  81.         zsendline((int)crc);  crc >>= 8;
  82.     }
  83. }
  84.  
  85.  
  86. /* Receive data subpacket RLE encoded with 32 bit FCS */
  87. zrdatr32(buf, length)
  88. register char *buf;
  89. {
  90.     register int c;
  91.     register UNSL long crc;
  92.     register char *end;
  93.     register int d;
  94.  
  95.     crc = 0xFFFFFFFFL;  Rxcount = 0;  end = buf + length;
  96.     d = 0;    /* Use for RLE decoder state */
  97.     while (buf <= end) {
  98.         if ((c = zdlread()) & ~0377) {
  99. crcfoo:
  100.             switch (c) {
  101.             case GOTCRCE:
  102.             case GOTCRCG:
  103.             case GOTCRCQ:
  104.             case GOTCRCW:
  105.                 d = c;  c &= 0377;
  106.                 crc = UPDC32(c, crc);
  107.                 if ((c = zdlread()) & ~0377)
  108.                     goto crcfoo;
  109.                 crc = UPDC32(c, crc);
  110.                 if ((c = zdlread()) & ~0377)
  111.                     goto crcfoo;
  112.                 crc = UPDC32(c, crc);
  113.                 if ((c = zdlread()) & ~0377)
  114.                     goto crcfoo;
  115.                 crc = UPDC32(c, crc);
  116.                 if ((c = zdlread()) & ~0377)
  117.                     goto crcfoo;
  118.                 crc = UPDC32(c, crc);
  119.                 if (crc != 0xDEBB20E3) {
  120.                     zperr(badcrc);
  121.                     return ERROR;
  122.                 }
  123.                 Rxcount = length - (end - buf);
  124. #ifndef DSZ
  125.                 vfile("zrdatr32: %d %s", Rxcount,
  126.                   Zendnames[d-GOTCRCE&3]);
  127. #endif
  128.                 return d;
  129.             case GOTCAN:
  130.                 zperr("Sender Canceled");
  131.                 return ZCAN;
  132.             case TIMEOUT:
  133.                 zperr("TIMEOUT");
  134.                 return c;
  135.             default:
  136.                 zperr("Bad data subpacket");
  137.                 return c;
  138.             }
  139.         }
  140.         crc = UPDC32(c, crc);
  141.         switch (d) {
  142.         case 0:
  143.             if (c == ZRESC) {
  144.                 d = -1;  continue;
  145.             }
  146.             *buf++ = c;  continue;
  147.         case -1:
  148.             if (c >= 040 && c < 0100) {
  149.                 d = c - 035; c = 040;  goto spaces;
  150.             }
  151.             if (c == 0100) {
  152.                 d = 0;
  153.                 *buf++ = ZRESC;  continue;
  154.             }
  155.             d = c;  continue;
  156.         default:
  157.             d -= 0100;
  158.             if (d < 1)
  159.                 goto badpkt;
  160. spaces:
  161.             if ((buf + d) > end)
  162.                 goto badpkt;
  163.             while ( --d >= 0)
  164.                 *buf++ = c;
  165.             d = 0;  continue;
  166.         }
  167.     }
  168. badpkt:
  169.     zperr("Data subpacket too long");
  170.     return ERROR;
  171. }
  172.  
  173.